package com.anypi;

import java.io.IOException;

import com.pi4j.io.gpio.GpioController;
import com.pi4j.io.gpio.GpioFactory;
import com.pi4j.io.gpio.GpioPinDigitalInput;
import com.pi4j.io.gpio.RaspiPin;
import com.pi4j.wiringpi.Spi;

public class CC1101 extends SpiRF {

	private GpioController gpio = GpioFactory.getInstance();
	public GpioPinDigitalInput gdo0;
	public int frequency = 0;

	public CC1101(int frequency) throws IOException {

		gdo0 = gpio.provisionDigitalInputPin(RaspiPin.GPIO_06);
		super.setFrequency(frequency);
		this.frequency = frequency;
	}

	public void writeSettings() {

		writeRegister(CC1101Reg.IOCFG0.getValue(), 0x06); // IOCFG0 GDO0 Output
															// Pin Configuration
		writeRegister(CC1101Reg.FIFOTHR.getValue(), 0x4F); // FIFOTHR RX FIFO
															// and TX FIFO
															// Thresholds
		writeRegister(CC1101Reg.PKTCTRL0.getValue(), 0x02); // PKTCTRL0 Packet
															// Automation
															// Control
		writeRegister(CC1101Reg.PKTCTRL1.getValue(), 0xC0);
		writeRegister(CC1101Reg.FSCTRL1.getValue(), 0x06); // FSCTRL1 Frequency
															// Synthesizer
															// Control
		writeRegister(CC1101Reg.FREQ2.getValue(), 0x10); // FREQ2 Frequency
															// Control
															// Word.getValue(),
															// High Byte
		writeRegister(CC1101Reg.FREQ1.getValue(), 0xAF); // FREQ1 Frequency
															// Control
															// Word.getValue(),
															// Middle Byte
		writeRegister(CC1101Reg.FREQ0.getValue(), 0x75); // FREQ0 Frequency
															// Control
															// Word.getValue(),
															// Low Byte
		writeRegister(CC1101Reg.MDMCFG4.getValue(), 0xF6); // MDMCFG4 Modem
															// Configuration
		writeRegister(CC1101Reg.MDMCFG3.getValue(), 0x83); // MDMCFG3 Modem
															// Configuration
		writeRegister(CC1101Reg.MDMCFG2.getValue(), 0x16); // MDMCFG2 Modem
															// Configuration
		writeRegister(CC1101Reg.DEVIATN.getValue(), 0x15); // DEVIATN Modem
															// Deviation Setting
		writeRegister(CC1101Reg.MCSM0.getValue(), 0x18); // MCSM0 Main Radio
															// Control State
															// Machine
															// Configuration
		writeRegister(CC1101Reg.FOCCFG.getValue(), 0x16); // FOCCFG Frequency
															// Offset
															// Compensation
															// Configuration
		writeRegister(CC1101Reg.WORCTRL.getValue(), 0xFB); // WORCTRL Wake On
															// Radio Control
		writeRegister(CC1101Reg.FSCAL3.getValue(), 0xE9); // FSCAL3 Frequency
															// Synthesizer
															// Calibration
		writeRegister(CC1101Reg.FSCAL2.getValue(), 0x2A); // FSCAL2 Frequency
															// Synthesizer
															// Calibration
		writeRegister(CC1101Reg.FSCAL1.getValue(), 0x00); // FSCAL1 Frequency
															// Synthesizer
															// Calibration
		writeRegister(CC1101Reg.FSCAL0.getValue(), 0x1F); // FSCAL0 Frequency
															// Synthesizer
															// Calibration
		writeRegister(CC1101Reg.TEST2.getValue(), 0x81); // FSCAL2 Frequency
															// Synthesizer
															// Calibration
		writeRegister(CC1101Reg.TEST1.getValue(), 0x35); // FSCAL1 Frequency
															// Synthesizer
															// Calibration
		writeRegister(CC1101Reg.TEST0.getValue(), 0x09); // FSCAL0 Frequency
															// Synthesizer
															// Calibration

		writeRegister(CC1101Reg.SYNC0.getValue(), 0xAA);
		writeRegister(CC1101Reg.SYNC1.getValue(), 0xAA);
	}

	public void sendCommand(CC1101Command command) {

		byte packet[] = new byte[1];
		packet[0] = command.getValue();

		Spi.wiringPiSPIDataRW(0, packet, 1);
	}

	public void sendPacket(byte[] buffer, int size) {

		this.writeBusrtRegister(CC1101Reg.TXFIFO.getValue(), buffer, size);
		sendCommand(CC1101Command.STX); // transmit packet
		while (gdo0.isLow())
			;
		while (gdo0.isHigh())
			;
		sendCommand(CC1101Command.SIDLE); // go to idle mode
	}

	public void initRadio() throws InterruptedException,
			IOException {

		// Reset CC1101 and write settings
		sendCommand(CC1101Command.SRES);
		writeSettings();

		// Start calibration
		sendCommand(CC1101Command.SCAL);
		Thread.sleep(200);

		sendCommand(CC1101Command.SFTX); // Flush TX FIFO
		sendCommand(CC1101Command.SFRX); // Flush RX FIFO
		sendCommand(CC1101Command.SIDLE); // Go to idle mode
		Thread.sleep(200);

	}
}
